package com.practice.rpc.server;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Method;
import java.net.Socket;

import com.practice.rpc.client.RpcRequest;

public class ProcessorHandler implements Runnable {
	
	private Socket socket;
	private Object service;

	public ProcessorHandler(Socket socket, Object service) {
		super();
		this.socket = socket;
		this.service = service;
	}

	@Override
	public void run() {
		ObjectInputStream in = null;
		ObjectOutputStream out = null;
		try {
			in = new ObjectInputStream(socket.getInputStream());
			
			RpcRequest request = (RpcRequest) in.readObject();
			
			Object result = invoke(request);
			
			out = new ObjectOutputStream(socket.getOutputStream());
			out.writeObject(result);
			out.flush();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			} 
			if (out != null) {
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	public Object invoke(RpcRequest request) throws Exception {
		Object[] args = request.getParameters();
		Class<?>[] types = new Class[args.length];
		for (int i = 0; i < args.length; i++) {
			types[i] = args[i].getClass();
		}
		
		Method method = service.getClass().getMethod(request.getMethodName(), types);
		return method.invoke(service, args);
	}

}
